/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package digitaldreamers.games.ddmonsters.servers.gameserver.configurations;

import digitaldreamers.games.ddmonsters.servers.gameserver.components.PlayerComponent;
import java.util.HashMap;

/**
 *
 * @author DaoLe
 */
public class Configuration {
    // <editor-fold defaultstate="collapsed" desc="Constants">
    
    // <editor-fold defaultstate="collapsed" desc="Server configurations">
    public static final int SERVER_PORT = 7777;
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="Database configurations">
    public static final String DATABASE_SERVER_NAME = "localhost";
    public static final int DATABASE_SERVER_PORT = 3306;
    public static final String DATABASE_NAME = "2DMonsters";
    public static final String DATABASE_USERNAME = "root";
    public static final String DATABASE_PASSWORD = "";
    public static final int DATABASE_TIMEOUT = 30;
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="Configuration types">
    private static final int PACKET_CONFIGURATION = 0;
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="Packet configurations">
    
    // <editor-fold defaultstate="collapsed" desc="Java packet names">
    public static final String RECEIVING_PACKET    = "digitaldreamers.games.ddmonsters.servers.gameserver.network.packets.receiving.";
    public static final String SENDING_PACKET      = "digitaldreamers.games.ddmonsters.servers.gameserver.network.packets.sending.";
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="Packet Ids">
    
    // <editor-fold defaultstate="collapsed" desc="Receiving">
    
    // <editor-fold defaultstate="collapsed" desc="CONNECTED">
    /**
     * ID = 1
     */
    public static final int RECEIVING_PACKET_ID__LOGIN_BY_UIID_REQUEST = 1;
    
    /**
     * ID = 2
     */
    public static final int RECEIVING_PACKET_ID__LOGIN_BY_LOGIN_AND_PASSWORD_REQUEST = RECEIVING_PACKET_ID__LOGIN_BY_UIID_REQUEST + 1;
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="NOT_IN_ROOM">
    /**
     * ID = 3
     */
    public static final int GET_ROOM_LIST_REQUEST_ID    = RECEIVING_PACKET_ID__LOGIN_BY_LOGIN_AND_PASSWORD_REQUEST + 1;
    
    /**
     * ID = 4
     */
    public static final int CREATE_ROOM_REQUEST_ID      = GET_ROOM_LIST_REQUEST_ID + 1;
    
    /**
     * ID = 4
     */
    public static final int JOIN_ROOM_REQUEST_ID        = CREATE_ROOM_REQUEST_ID + 1;
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="IN_ROOM">
    
    // <editor-fold defaultstate="collapsed" desc="WAITING">
    /**
     * ID = 5
     */
    public static final int LEAVE_ROOM_REQUEST_ID        = JOIN_ROOM_REQUEST_ID + 1;
    
    /**
     * ID = 6
     */
    public static final int SET_READY_STATE_REQUEST_ID   = LEAVE_ROOM_REQUEST_ID + 1;
    
    /**
     * ID = 7
     */
    public static final int START_DUEL_REQUEST_ID        = SET_READY_STATE_REQUEST_ID + 1;
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="CLIENT_NOT_READY">
    /**
     * ID = 8
     */
    public static final int CLIENT_READY_REQUEST_ID = START_DUEL_REQUEST_ID + 1;
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="CLIENT_READY">
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="DUELING">
    /**
     * ID = 9
     */
    public static final int SUMMON_MONSTER_REQUEST_ID = CLIENT_READY_REQUEST_ID + 1;
    // </editor-fold>
    
    // </editor-fold>
    
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="Sending">
    /**
     * ID = 1
     */
    public static final int SENDING_PACKET_ID__LOGIN_REQUEST_RESPONSE = 1;
    
    /**
     * ID = 2
     */
    public static final int GET_ROOM_LIST_REQUEST_RESPONSE_ID = SENDING_PACKET_ID__LOGIN_REQUEST_RESPONSE + 1;
    
    /**
     * ID = 3
     */
    public static final int CREATE_ROOM_REQUEST_RESPONSE_ID = GET_ROOM_LIST_REQUEST_RESPONSE_ID + 1;
    
    /**
     * ID = 4
     */
    public static final int NEW_ROOM_CREATED_PACKET_ID = CREATE_ROOM_REQUEST_RESPONSE_ID + 1;
    
    /**
     * ID = 5
     */
    public static final int JOIN_ROOM_REQUEST_RESPONSE_ID = NEW_ROOM_CREATED_PACKET_ID + 1;
    
    /**
     * ID = 6
     */
    public static final int PLAYER_JOIN_ROOM_PACKET_ID = JOIN_ROOM_REQUEST_RESPONSE_ID + 1;
    
    /**
     * ID = 7
     */
    public static final int LEAVE_ROOM_REQUEST_RESPONSE_ID = PLAYER_JOIN_ROOM_PACKET_ID + 1;
    
    /**
     * ID = 8
     */
    public static final int PLAYER_LEAVE_ROOM_PACKET_ID = LEAVE_ROOM_REQUEST_RESPONSE_ID + 1;
    
    /**
     * ID = 9
     */
    public static final int SET_READY_STATE_REQUEST_RESPONSE_ID = PLAYER_LEAVE_ROOM_PACKET_ID + 1;
    
    /**
     * ID = 10
     */
    public static final int PLAYER_IS_READY_PACKET_ID = SET_READY_STATE_REQUEST_RESPONSE_ID + 1;
    
    /**
     * ID = 11
     */
    public static final int ROOM_STATE_CHANGED_PACKET_ID = PLAYER_IS_READY_PACKET_ID + 1;
    
    /**
     * ID = 12
     */
    public static final int ROOM_REMOVED_PACKET_ID = ROOM_STATE_CHANGED_PACKET_ID + 1;
    
    /**
     * ID = 13
     */
    public static final int START_DUEL_REQUEST_RESPONSE_ID = ROOM_REMOVED_PACKET_ID + 1;
    
    /**
     * ID = 14
     */
    public static final int DUEL_STARTED_PACKET_ID = START_DUEL_REQUEST_RESPONSE_ID + 1;
    
    /**
     * ID = 15
     */
    public static final int TURN_PHASE_CHANGED_PACKET_ID = DUEL_STARTED_PACKET_ID + 1;
    
    /**
     * ID = 16
     */
    public static final int TURN_CHANGED_PACKET_ID = TURN_PHASE_CHANGED_PACKET_ID + 1;
    
    /**
     * ID = 17
     */
    public static final int DUEL_ENDED_PACKET_ID = TURN_CHANGED_PACKET_ID + 1;
    
    /**
     * ID = 18
     */
    public static final int CARDS_DRAWN_PACKET_ID = DUEL_ENDED_PACKET_ID + 1;
    
    /**
     * ID = 19
     */
    public static final int SUMMON_MONSTER_REQUEST_RESPONSE_ID = CARDS_DRAWN_PACKET_ID + 1;
    
    /**
     * ID = 20
     */
    public static final int OPPONENT_SUMMON_MONSTER_PACKET_ID = SUMMON_MONSTER_REQUEST_RESPONSE_ID + 1;
    
    // </editor-fold>
    
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="Packet class names">
    
    // <editor-fold defaultstate="collapsed" desc="Receiving">
    
    // <editor-fold defaultstate="collapsed" desc="CONNECTED">
    
    private static final String PACKET_CLASS_NAME__LOGIN_BY_UIID_REQUEST = "RLoginByUiidRequest";
    
    private static final String PACKET_CLASS_NAME__LOGIN_BY_LOGIN_AND_PASSWORD_REQUEST = "RLoginByLoginAndPasswordRequest";
    
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="NOT_IN_ROOM">
    private static final String GET_ROOM_LIST_REQUEST_CLASS_NAME  = "RGetRoomListRequest";
    private static final String CREATE_ROOM_REQUEST_CLASS_NAME    = "RCreateRoomRequest";
    private static final String JOIN_ROOM_REQUEST_CLASS_NAME      = "RJoinRoomRequest";
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="IN_ROOM">
    
    // <editor-fold defaultstate="collapsed" desc="WAITING">
    private static final String LEAVE_ROOM_REQUEST_CLASS_NAME         = "RLeaveRoomRequest";
    private static final String SET_READY_STATE_REQUEST_CLASS_NAME    = "RSetReadyStateRequest";
    private static final String START_DUEL_REQUEST_CLASS_NAME         = "RStartDuelRequest";
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="CLIENT_NOT_READY">
    private static final String CLIENT_READY_REQUEST_CLASS_NAME = "RClientReadyRequest";
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="CLIENT_READY">
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="DUELING">
    private static final String SUMMON_MONSTER_REQUEST_CLASS_NAME = "RSummonMonsterRequest";
    // </editor-fold>
    
    // </editor-fold>
    
    // </editor-fold>
    
    // </editor-fold>
    
    // </editor-fold>
    
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="Statics Members">
    private static Configuration instance;
    private static final Object lockObj = new Object();
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="Members">
    private HashMap<Integer, Object> mConfigurations;
    
    private HashMap<PlayerComponent.PlayerStates, HashMap> mStateBasedReceivablePackets;
    private HashMap<Integer, String> mPacketIDsAndNamesMap__Connected;
    private HashMap<Integer, String> mPacketIDsAndNamesMap__NotInRoom;
    private HashMap<PlayerComponent.InRoomSubstates, HashMap> mPacketIDsAndNamesMap__InRoom;
    private HashMap<Integer, String> mPacketIDsAndNamesMap__Waiting;
    private HashMap<Integer, String> mPacketIDsAndNamesMap__ClientNotReady;
    private HashMap<Integer, String> mPacketIDsAndNamesMap__Dueling;
    // </editor-fold>
    
    public HashMap getConfigurations() {
        return mConfigurations;
    }
    
    private Configuration() {
        initialize();
    }
    
    public static Configuration getInstance() {
        if(instance == null) {
            synchronized(lockObj) {
                if(instance == null) {
                    instance = new Configuration();
                }
            }
        }
        return instance;
    }
    
    public String getPacketClassName(int pPacketID, PlayerComponent.PlayerStates pState, PlayerComponent.InRoomSubstates pInRoomSubstate) {
        String packetClassName = null;
        switch(pState) {
            case CONNECTED:
                packetClassName = mPacketIDsAndNamesMap__Connected.get(pPacketID);
                break;
            case NOT_IN_ROOM:
                packetClassName = mPacketIDsAndNamesMap__NotInRoom.get(pPacketID);
                break;
            case IN_ROOM:
                switch(pInRoomSubstate) {
                    case WAITING:
                        packetClassName = mPacketIDsAndNamesMap__Waiting.get(pPacketID);
                        break;
                    case CLIENT_NOT_READY:
                        packetClassName = mPacketIDsAndNamesMap__ClientNotReady.get(pPacketID);
                        break;
                    case CLIENT_READY:
                        break;
                    case DUELING:
                        packetClassName = mPacketIDsAndNamesMap__Dueling.get(pPacketID);
                        break;
                    // Dao: Need more substate processing.    
                    default:
                        break;
                }
                break;
            default:
                break;
        }
        return packetClassName;
    }
    
    private void initialize() {
        mConfigurations = new HashMap<>();
        
        // <editor-fold defaultstate="collapsed" desc="Packet configurations">
        mStateBasedReceivablePackets = new HashMap<>();
        
        // <editor-fold defaultstate="collapsed" desc="CONNECTED">
        mPacketIDsAndNamesMap__Connected = new HashMap();
        mPacketIDsAndNamesMap__Connected.put(RECEIVING_PACKET_ID__LOGIN_BY_UIID_REQUEST, PACKET_CLASS_NAME__LOGIN_BY_UIID_REQUEST);
        mPacketIDsAndNamesMap__Connected.put(RECEIVING_PACKET_ID__LOGIN_BY_LOGIN_AND_PASSWORD_REQUEST, PACKET_CLASS_NAME__LOGIN_BY_LOGIN_AND_PASSWORD_REQUEST);
        mStateBasedReceivablePackets.put(PlayerComponent.PlayerStates.CONNECTED, mPacketIDsAndNamesMap__Connected);
        // </editor-fold>
        
        // <editor-fold defaultstate="collapsed" desc="NOT_IN_ROOM">
        mPacketIDsAndNamesMap__NotInRoom = new HashMap();
        mPacketIDsAndNamesMap__NotInRoom.put(GET_ROOM_LIST_REQUEST_ID, GET_ROOM_LIST_REQUEST_CLASS_NAME);
        mPacketIDsAndNamesMap__NotInRoom.put(CREATE_ROOM_REQUEST_ID, CREATE_ROOM_REQUEST_CLASS_NAME);
        mPacketIDsAndNamesMap__NotInRoom.put(JOIN_ROOM_REQUEST_ID, JOIN_ROOM_REQUEST_CLASS_NAME);
        mStateBasedReceivablePackets.put(PlayerComponent.PlayerStates.NOT_IN_ROOM, mPacketIDsAndNamesMap__NotInRoom);
        // </editor-fold>
        
        // <editor-fold defaultstate="collapsed" desc="IN_ROOM">
        mPacketIDsAndNamesMap__InRoom = new HashMap<>();
        
        // <editor-fold defaultstate="collapsed" desc="WAITING">
        mPacketIDsAndNamesMap__Waiting = new HashMap<>();
        mPacketIDsAndNamesMap__Waiting.put(LEAVE_ROOM_REQUEST_ID, LEAVE_ROOM_REQUEST_CLASS_NAME);
        mPacketIDsAndNamesMap__Waiting.put(SET_READY_STATE_REQUEST_ID, SET_READY_STATE_REQUEST_CLASS_NAME);
        mPacketIDsAndNamesMap__Waiting.put(START_DUEL_REQUEST_ID, START_DUEL_REQUEST_CLASS_NAME);
        mPacketIDsAndNamesMap__InRoom.put(PlayerComponent.InRoomSubstates.WAITING, mPacketIDsAndNamesMap__Waiting);
        // </editor-fold>
        
        // <editor-fold defaultstate="collapsed" desc="CLIENT_NOT_READY">
        mPacketIDsAndNamesMap__ClientNotReady = new HashMap<>();
        mPacketIDsAndNamesMap__ClientNotReady.put(CLIENT_READY_REQUEST_ID, CLIENT_READY_REQUEST_CLASS_NAME);
        mPacketIDsAndNamesMap__InRoom.put(PlayerComponent.InRoomSubstates.CLIENT_NOT_READY, mPacketIDsAndNamesMap__ClientNotReady);
        // </editor-fold>
        
        // <editor-fold defaultstate="collapsed" desc="CLIENT_READY">
        // </editor-fold>
        
        // <editor-fold defaultstate="collapsed" desc="DUELING">
        mPacketIDsAndNamesMap__Dueling = new HashMap<>();
        mPacketIDsAndNamesMap__Dueling.put(SUMMON_MONSTER_REQUEST_ID, SUMMON_MONSTER_REQUEST_CLASS_NAME);
        mPacketIDsAndNamesMap__InRoom.put(PlayerComponent.InRoomSubstates.DUELING, mPacketIDsAndNamesMap__Dueling);
        // </editor-fold>
        
        mStateBasedReceivablePackets.put(PlayerComponent.PlayerStates.IN_ROOM, mPacketIDsAndNamesMap__InRoom);
        // </editor-fold>
        
        mConfigurations.put(PACKET_CONFIGURATION, mStateBasedReceivablePackets);
        // </editor-fold>
    }
}
